﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySkiPatrolEntity;
using MySkiPatrolDAL;
using MySkiPatrolVAL;
using WorldWeatherOnline.LocalWeather;
using WorldWeatherOnline.LocationSearch;
using WorldWeatherOnline.MarineWeather;
using WorldWeatherOnline.TimeZone;

namespace MySkiPatrolBLL
{
    public class PatrolBLO
    {
        PatrolDAO dao = new PatrolDAO();
        
        public Patrols GetPatrolList()
        {
            return dao.GetPatrolList();
        }

        public Patrol GetPatrol(Patrol data)
        {
            if (!string.IsNullOrEmpty(data.ID)) data = dao.GetPatrolByID(data);
            if (!string.IsNullOrEmpty(data.SubDomain)) data = dao.GetPatrolBySubDomain(data);

            if (data.DataTransaction.Success)
            {
                data.DataTransaction.PatrolPrefix = data.dbPrefix;
                //attach the appsettings
                data.ApplicationSettings = dao.GetAppSettings(data);

                data.WeatherForecast = this.GetWeatherForecast(data.WeatherForecast,data.DataTransaction.PatrolPrefix);
            }



            return data;
        }

        public Patrol GetPatrolByID(Patrol data)
        {
            return dao.GetPatrolByID(data);
        }

        public Patrol PutPatrol(Patrol data)
        {
            switch (data.DataTransaction.Action)
            {
                case DataAction.Delete:
                    break;
                case DataAction.Update:
                    break;
                case DataAction.Add:
                    data.ID = Guid.NewGuid().ToString();

                    data = PatrolVLO.NewPatrol(data);

                    if (data.DataTransaction.TransactionErrors == null) data.DataTransaction.TransactionErrors = new List<Error>();
                    if (data.DataTransaction.TransactionLog == null) data.DataTransaction.TransactionLog = new List<LogEntry>();

                    if (data.DataTransaction.Success)
                    {
                        //lots to do here...try to create all the tables...we report the errors for each in the log
                        data = dao.CreateMemberTable(data);
                        data = dao.CreateApplicationSettingTable(data);
                        data = dao.CreateEmailAddressTable(data);
                        data = dao.CreateEmailLogTable(data);
                        data = dao.CreateEmailTemplateTable(data);
                        data = dao.CreateEventTable(data);
                        data = dao.CreateGroupRoleTable(data);
                        data = dao.CreateGroupTable(data);
                        data = dao.CreateRoleMemberTable(data);
                        data = dao.CreateRoleTable(data);
                        data = dao.CreateArticleTable(data);
                        data = dao.CreateServiceDaysTable(data);
                        data = dao.CreateDailySignInTable(data);
                        data = dao.CreateMemberIDCardsTable(data);

                        data = dao.AddPatrol(data);
                    }

                    break;

            }

            return data;
        }

        public WeatherForecast GetWeatherForecast(WeatherForecast request, string patrolPrefix)
        {
            List<WeatherForecast> forecasts = new List<WeatherForecast>();
            WeatherForecast myReturn = new WeatherForecast();

            try
            {
                //get the data from the DAO
                forecasts = dao.GetWeatherForecasts(patrolPrefix);

                //check the data for refresh
                foreach (WeatherForecast forecast in forecasts)
                {
                    bool refreshed = false;
                    string refreshedHTML = string.Empty;
                    if (forecast.HTML == string.Empty)
                    {
                        //refresh
                        LocalWeather myData = GetLocalWeather(forecast.Location, forecast.DayCount);
                        forecast.HTML = FormatLocalWeather_HTML(forecast.Name, myData, int.Parse(forecast.DayCount));
                        if (!forecast.HTML.ToUpper().Contains("NO DATA")) { forecast.LastUpdate = DateTime.Now; }
                        refreshed = true;
                    }
                    else
                    {
                        if ((forecast.LastUpdate == null) || (forecast.LastUpdate == DateTime.MinValue))
                        {
                            //refresh
                            LocalWeather myData = GetLocalWeather(forecast.Location, forecast.DayCount);
                            forecast.HTML = FormatLocalWeather_HTML(forecast.Name, myData, int.Parse(forecast.DayCount));
                            if (!forecast.HTML.ToUpper().Contains("NO DATA")) { forecast.LastUpdate = DateTime.Now; }
                            refreshed = true;
                        }
                        else
                        {
                            if (forecast.LastUpdate.AddMinutes(double.Parse(forecast.RefreshInterval)) <= DateTime.Now)
                            {
                                //refresh
                                LocalWeather myData = GetLocalWeather(forecast.Location, forecast.DayCount);
                                forecast.HTML = FormatLocalWeather_HTML(forecast.Name, myData, int.Parse(forecast.DayCount));
                                if (!forecast.HTML.ToUpper().Contains("NO DATA")) { forecast.LastUpdate = DateTime.Now; }
                                refreshed = true;
                            }
                        }
                    }

                    if (refreshed)
                    {
                        //save the updated data...
                        dao.UpdateWeatherData(forecast, patrolPrefix);
                    }
                }

                //return the forecast(s)
                //foreach (WeatherForecast forecast in forecasts)
                //{
                //    if (forecast.ID == request.ID)
                //    {
                        myReturn = forecasts[0];
                        //break;
                //    }
                //}
            }
            catch (Exception ex)
            {

            }

            return myReturn;
        }

        private int ConvertCelsiusToFahrenheit(double c)
        {
            return (int)((9.0 / 5.0) * c) + 32;
        }

        private double ConvertFahrenheitToCelsius(double f)
        {
            return (5.0 / 9.0) * (f - 32);
        }

        private string FormatLocalWeather_HTML(string location, LocalWeather forecast, int days)
        {
            StringBuilder html = new StringBuilder();

            try
            {

                html.Append("<div class='rightblock'>");
                html.Append("<table border=0 style=\"width:100%;\">");
                html.Append("<tr>");
                html.Append("<td colspan='4'><strong>" + location + "</strong><br/><span style='font-size: 8px'>" + forecast.data.current_Condition[0].observation_time.AddHours(-4).ToShortDateString() + " @ " + forecast.data.current_Condition[0].observation_time.AddHours(-4).ToShortTimeString() + "</span></td>");
                html.Append("</tr>");
                html.Append("<tr>");
                html.Append("<td rowspan='5'><image width='40px' src='" + forecast.data.current_Condition[0].weatherIconUrl[0].value + "'/><br /><strong>" + ConvertCelsiusToFahrenheit(forecast.data.current_Condition[0].temp_C).ToString() + "&#176;F</strong></td>");
                html.Append("</tr>");
                html.Append("<tr>");
                html.Append("<td  rowspan='4'>&nbsp;</td>");
                html.Append("</tr>");
                html.Append("<tr>");
                html.Append("<td>" + forecast.data.current_Condition[0].weatherDesc[0].value + "</td>");
                html.Append("</tr>");
                html.Append("<tr>");
                html.Append("<td>Wind: " + forecast.data.current_Condition[0].winddir16Point + " at " + forecast.data.current_Condition[0].windspeedMiles + " mph</td>");
                html.Append("</tr>");
                html.Append("<tr>");
                html.Append("<td>Humidity: " + forecast.data.current_Condition[0].humidity.ToString() + " %</td>");
                html.Append("</tr>");
                html.Append("</table>");
                html.AppendLine("");
                html.Append("<br/>");
                html.Append("<table style=\"width:100%;\">");
                html.Append("<tr>");
                html.Append("<td style='text-align: center'>" + forecast.data.weather[0].date.ToLongDateString().Substring(0, 3) + "</td>");

                html.Append("<td style='text-align: center'>" + forecast.data.weather[1].date.ToLongDateString().Substring(0, 3) + "</td>");

                html.Append("<td style='text-align: center'>" + forecast.data.weather[2].date.ToLongDateString().Substring(0, 3) + "</td>");
                html.Append("</tr>");
                html.AppendLine("");
                html.Append("<tr>");
                html.Append("<td style='text-align: center'><image width='40px' src='" + forecast.data.weather[0].weatherIconUrl[0].value + "'/></td>");

                html.Append("<td style='text-align: center'><image width='40px' src='" + forecast.data.weather[1].weatherIconUrl[0].value + "'/></td>");

                html.Append("<td style='text-align: center'><image width='40px' src='" + forecast.data.weather[2].weatherIconUrl[0].value + "'/></td>");
                html.Append("</tr>");
                html.AppendLine("");
                html.Append("<tr>");
                html.Append("<td style='text-align: center'>H " + forecast.data.weather[0].tempMaxF + "&#176; <br />L " + forecast.data.weather[0].tempMinF + "&#176;</td>");

                html.Append("<td style='text-align: center'>H " + forecast.data.weather[1].tempMaxF + "&#176; <br />L " + forecast.data.weather[1].tempMinF + "&#176;</td>");

                html.Append("<td style='text-align: center'>H " + forecast.data.weather[2].tempMaxF + "&#176; <br />L " + forecast.data.weather[2].tempMinF + "&#176;</td>");
                html.Append("</tr>");
                html.Append("</table>");
                html.AppendLine("");
                html.Append("<table width='100%'>");
                html.Append("<tr>");
                html.Append("<td style='text-align: center' colspan='2'>Powered by<br />");
                html.Append("<a href='http://www.worldweatheronline.com/' title='Free local weather content provider' target='_blank'>World Weather Online</a>");
                html.Append("</td>");
                html.Append("</tr>");
                html.Append("</table>");
                html.Append("</div>	");
            }
            catch (Exception ex)
            {
                //something happened with fetching the data...
                //need to report something...
                html = new StringBuilder();
                html.Append("<div class='rightblock'>");
                html.Append("<table border=0>");
                html.Append("<tr>");
                html.Append("<td colspan='4'><strong>" + location + "</strong></td>");
                html.Append("</tr>");
                html.Append("<tr>");
                html.Append("<td colspan='4'>No data available</td>");
                html.Append("</tr></table></div>");
            }





            //html.Append("<div class='rightblock'>");
            //html.Append("<table border='0'>");

            ////Current Conditions
            //html.Append("<tr><td colspan='2'><strong>Currently at<br />" + location + "</strong></td></tr>");
            //html.Append("<tr><td rowspan='4'><image src='" + forecast.data.current_Condition[0].weatherIconUrl[0].value + "'/></td></tr>");
            //html.Append("<tr><td>" + forecast.data.current_Condition[0].weatherDesc[0].value + "</td></tr>");
            //html.Append("<tr><td>Temp: " + ConvertCelsiusToFahrenheit(forecast.data.current_Condition[0].temp_C).ToString() + "&#176;F</td></tr>");
            //html.Append("<tr><td>Visibility: " + forecast.data.current_Condition[0].visibility + "</td></tr>");
            ////spacer
            //html.Append("<tr><td></td><td></td></tr>");

            //for (int item = 1; item < days; item++)
            //{
            //    //forecast day 1 (current day)
            //    html.Append("<tr><td colspan='2'><strong>" + forecast.data.weather[item].date.ToLongDateString() + "</strong></td></tr>");
            //    html.Append("<tr><td rowspan='4'><image src='" + forecast.data.weather[item].weatherIconUrl[0].value + "'/></td></tr>");
            //    html.Append("<tr><td>" + forecast.data.weather[item].weatherDesc[0].value + "</td></tr>");
            //    html.Append("<tr><td>High: " + forecast.data.weather[item].tempMaxF + "&#176;F</td></tr>");
            //    html.Append("<tr><td>Low: " + forecast.data.weather[item].tempMinF + "&#176;F</td></tr>");
            //    //spacer
            //    html.Append("<tr><td></td><td></td></tr>");
            //}

            //html.Append("<tr><td align='center' colspan='2'>Powered by<br /><a href='http://www.worldweatheronline.com/' title='Free local weather content provider' target='_blank'>World Weather Online</a></td></tr>");
            //html.Append("</table></div>");
            return html.ToString();
        }

        private LocalWeather GetLocalWeather(string location, string days)
        {
            LocalWeather myReturn = new LocalWeather();

            LocalWeatherInput myInput = new LocalWeatherInput();
            myInput.query = location;
            myInput.num_of_days = days;
            myInput.format = "JSON";

            FreeAPI api = new FreeAPI();
            myReturn = api.GetLocalWeather(myInput);

            return myReturn;

        }
    }
}
